package pay

import (
	"context"
	"fmt"
	"github.com/smartwalle/alipay/v3"
	"log"
	"net/http"
	"strconv"
	"time"
)

func NewPayClient() *alipay.Client {
	APP_ID := "9021000131619667"
	PUBLIC_KEY := "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyGFDVI+EQXkmuE59Yri6d3p19dw6IlXzS+3H0++ijL5W8hcaTdqM+3AY3/DcoTAg9YXgHmzt9+7cE98vUkrqWcZqhvguSwIB363vDepudXs2MKrsQnn4zM7yo5JaWQ/Npizb9UMl4XZwPrNtRUaItkLKY9g/HgCLfEq5A93AkP+atz1iUJij8ddG2ld9tA/MEfzbtX3kmlymhOOoOOGY6yaQSVaCCBSqd4dpvw0tWSS0GakSQ3P8NxtZLQl4/li7h+KYdvnc1/xC0jEaQOrKFmGIp15n0xP4s4EJgS0ZjqfJ1UVlzIM+EcnOiLHuULUdPzEi81d2mFwiV1XYOp7ZHQIDAQAB"
	PRIVATE_KEY := "MIIEpQIBAAKCAQEA5Bzse8jax9CSx7+ZXcJOssaJpXAggd7fm4tcQSRwaAHMUmrDhWT6XaKIVZBAPtcsSu2VCGbWsokHlFw7Z3XNQaon9uH6ghc0vdRAGgVaaaGwsKVCvHxrP4ptquyT3aXiGEd4A4P7sonRkzLDDTkc6ZuVyomGsGo1df+OVbsxMKhPSdg9irGqVNTJklDXcp0jsilifWRfnEQulppzRO7Qev6G7WhsdHDLMCHTZF7qv5hWX6wlgB/tOy3wepEA6mNCKMFFHoGDztqhOhdMrPasfvuLAfuJ6jVUhuiYTzIqDzhRuezveBwPPFmWtjvhjNKlI5UEZv8yPwqCuaM3ETbLKwIDAQABAoIBAAOiQlImfPW56NytvK+1rLNEXmT4SExJVJ6RtcKD5haCENMvSDYTybk8IZfbWGqn2tjGuB0OJlVpwWknnvqi8cYeA8z3BJqV7A0qGGtRsoMERGBMAagnAz5b4ita4XAieFuSp+LGc3gAogoKQPkw87j09YnobvDYgEmE7KuI89umiwnDQpXR9xpE6AgFQgP6ZEr9FYsQV1c4fYp0UV7zrdixb6PxuFo8NZlEtcvnP8dt3BY7GRxXeSkdpEwLlnTLSZUbZ70wAwZu39K4idGxQ7FzOgeei6BdUStQOOdA7jIVWI6fqbflm2KMGTgBpgRet93RQAh0pdLr00Asi59dkeECgYEA81YwC48I6hSgcnO1z5r6VLtJABcct9kUZ88obU/qsSj11BYf4Ts+v97TnYaCHHVMefvTxVwnrBZN3ygohcOxn7Bfx1tEC5WWh9CL7S6hQvdF+WXubQPFoVlHTwth1eUFzcs8svCAu4DdLtK/0mgTPO1fjXSjjBC/29vg4cDsPbUCgYEA7/vryb+xWi+HJdmhZbM+si5yZklfljb3roRK1RgRqIwUYw3ggHHyVIS5WgHlthffGyRKUJWatL0zF8YtBGAi1GWAq7eH9iclI892pJYZPbUXx9bCwPfcMoiB2JiyjFCQB19ub6Q3dQsPlvF+gWg+29Hjmda6O1/pBAvootJzcV8CgYEAgYT3j79zbDzMZf8G39jKs7z4Dy8+HvFRtiuChiSKc/+sUVXxZA4HyVLOakNFD+azbR5ISv1RNHyuuEAEyaYu7iOP52nBnzTg6atsPzOZrC43tZa2wJnIYKhHl2AklBgR7cbmqQvwSV0+3YRZi6HP05c5S+6weoYTyO+RFDh+xh0CgYEArOgyu7qs2tDRrBjAq9jYvGKwtDf7ceyKyiexDxX3axv6eGAAOCthMTornckuK+PJMPIVxTf1LnH/RQrZVoS5s5Sqf46NnHIZ1VJeJjmrWAWJa8e1rHkpIxOtklR6mJRXIajFlhSYjHD6u4Ol5TEp0RHJzgajSbJR3kOCSwYcfTsCgYEAtHUEEm438vzNB6c/2UTekvkFToE59oynAzABIKdN+502rxsok0DFiAfRqMeMWckZ5wJuqXM4ylz98melFX+cnmDyFE6k2ndBIrIYQIACarZxetHXpLhNz4bbA1ZgITcW/2XOzKdMlvbdueI98uVA/zqKxHlib1jMlp0CdlnIxEs="
	var client, err = alipay.New(APP_ID, PRIVATE_KEY, false)
	if err != nil {
		fmt.Println(err)
		return nil
	}
	if err = client.LoadAliPayPublicKey(PUBLIC_KEY); err != nil {
		fmt.Println(err)
		return nil
	}
	return client
}

func Pays(orderSnc string, price string) (string, error) {
	client := NewPayClient()
	var p = alipay.TradeWapPay{}
	p.NotifyURL = "https://www.baidu.com/"   //设置支付宝异步通知的回调URL，当支付状态发生变化时，支付宝会向该URL发送通知。
	p.ReturnURL = "https://www.baidu.com/"   //设置支付宝同步通知的回调URL，支付完成后用户将跳转回该URL
	p.Subject = "支付" + orderSnc              //标题
	p.OutTradeNo = orderSnc                  //传递一个唯一单号
	p.TotalAmount = price                    //金额
	p.ProductCode = "FAST_INSTANT_TRADE_PAY" //产品代码
	currentTime := time.Now()
	unixTimestamp := currentTime.Unix()
	p.TimeoutExpress = strconv.FormatInt(unixTimestamp, 10) //设置超时时间，即订单有效期，以Unix时间戳形式表示。

	p.Body = "描述" //设置订单描述信息。
	var str, err = client.TradeWapPay(p)
	if err != nil {
		return "", err
	}
	// 这个 payURL 即是用于打开支付宝支付页面的 URL，可将输出的内容复制，到浏览器中访问该 URL 即可打开支付页面。
	fmt.Println(str.String())
	return str.String(), nil
}

// Refund 退款
func Refund(tradeNo string, refundAmount string) (*alipay.TradeRefundRsp, error) {
	client := NewPayClient()
	var p = alipay.TradeRefund{}
	p.RefundAmount = refundAmount
	p.TradeNo = tradeNo
	refunds, err := client.TradeRefund(context.Background(), p)
	if err != nil {
		return nil, err
	}
	return refunds, nil
}

// Callback 回调
func Callback(writer http.ResponseWriter, request *http.Request) string {
	client := NewPayClient()
	request.ParseForm()
	if err := client.VerifySign(request.Form); err != nil {
		log.Println("回调验证签名发生错误", err)
		writer.WriteHeader(http.StatusBadRequest)
		writer.Write([]byte("回调验证签名发生错误"))
		return "0"
	}
	log.Println("回调验证签名通过")
	// 示例一：使用已有接口进行查询
	var outTradeNo = request.Form.Get("out_trade_no")
	var p = alipay.TradeQuery{}
	p.OutTradeNo = outTradeNo

	rsp, err := client.TradeQuery(context.Background(), p)
	if err != nil {
		writer.WriteHeader(http.StatusBadRequest)
		writer.Write([]byte(fmt.Sprintf("验证订单 %s 信息发生错误: %s", outTradeNo, err.Error())))
		return "0"
	}

	if rsp.IsFailure() {
		writer.WriteHeader(http.StatusBadRequest)
		writer.Write([]byte(fmt.Sprintf("验证订单 %s 信息发生错误: %s-%s", outTradeNo, rsp.Msg, rsp.SubMsg)))
	}
	writer.WriteHeader(http.StatusOK)
	_, err = writer.Write([]byte(fmt.Sprintf("订单 %s 支付成功", outTradeNo)))
	if err != nil {
		return "0"
	}
	return outTradeNo
}
